home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / gcoope10.zip / STREAM.C < prev    next >
Text File  |  1994-07-23  |  11KB  |  556 lines

  1.  
  2. /*
  3.  
  4.     Stream object class definition for GCOOPE 1.0
  5.  
  6.     This class is for stream interface to user defined i/o objects
  7.  
  8.       released as PUBLIC DOMAIN 4/25/94 ported to GCOOPE 7/21/94
  9.  
  10.     A user defined i/o object is one that includes methods for
  11.     the generics described in the LowStream class definition.
  12.     (May, of course, be an inheritor of LowStream).
  13.  
  14. */
  15.  
  16.  
  17. #define CLASS Stream
  18.  
  19. #include "gcoope10.h"
  20. #include "stream.h"
  21. #include <stdarg.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. object CLASS;
  26.  
  27. extern object String;
  28.  
  29. typedef struct {
  30.     object        ioObj;
  31.     unsigned char * buffer;
  32.     unsigned char    hold;
  33.     short int    bsize;
  34.     short int    curPos;
  35.     unsigned    flags;
  36.      } instVars;
  37.  
  38.  
  39. USEGEN(getPos);
  40. USEGEN(setPos);
  41. USEGEN(strmErr);
  42. USEGEN(putByte);
  43. USEGEN(getByte);
  44. USEGEN(Putc);
  45. USEGEN(Getc);
  46. USEGEN(UnGet);
  47. USEGEN(Puts);
  48. USEGEN(Gets);
  49. USEGEN(Write);
  50. USEGEN(Read);
  51. USEGEN(SetBuf);
  52. USEGEN(Flush);
  53. USEGEN(clrErr);
  54. USEGEN(Stat);
  55. USEGEN(asString);
  56. USEGEN(addressOf);
  57.  
  58.  
  59. cmethod object m4New(object instance, object ioObj, const char * mode)
  60. {
  61. instVars * ivptr;
  62.  
  63. if(NULL==(ivptr=makeInst(&instance))) return 0L;
  64. ivptr->ioObj=ioObj;
  65. ivptr->flags=S_BIN;
  66. ivptr->buffer=NULL;
  67. if(NULL!=strchr(mode,'r')) ivptr->flags |= S_READ;
  68. if(NULL!=strchr(mode,'w')) ivptr->flags |= S_WRITE;
  69. if(NULL!=strchr(mode,'t')) ivptr->flags &= ~S_BIN;
  70. if(NULL!=strchr(mode,'+')) ivptr->flags |= S_RDWR;
  71.  
  72. return instance;
  73. }
  74.  
  75.  
  76. imethod object m4SetBuf(object instance,char * buffer,
  77.                     int type, word size)
  78. {
  79. instVars * ivptr;
  80.  
  81. if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
  82.  
  83. if(ivptr->buffer != NULL || size<=0) return FUNCFAIL;
  84. if(type==_IONBF) return FUNCFAIL;
  85. ivptr->buffer=(unsigned char *)buffer;
  86. ivptr->bsize=size;
  87. ivptr->flags|=S_BUF;
  88. if(type==_IOLBF) ivptr->flags|=S_LBUF;
  89. return FUNCOKAY;
  90. }
  91.  
  92.  
  93. imethod object m4Flush(object instance)
  94. {
  95. object (*wrDest)(object,char);
  96. unsigned char * ptrA;
  97. instVars *     ivptr;
  98.  
  99. if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
  100.  
  101. if(ivptr->flags & S_WRITE && ivptr->curPos>0)
  102.     {
  103.     (method) wrDest=g(GEN(putByte), ivptr->ioObj);
  104.     for(ptrA=ivptr->buffer;ivptr->curPos>0;ivptr->curPos--,ptrA++)
  105.     {
  106.     if(wrDest(ivptr->ioObj,*ptrA))
  107.         {
  108.         ivptr->flags |= S_EOS;
  109.         return FUNCFAIL;
  110.         }
  111.     }
  112.     }
  113. else ivptr->curPos=0;
  114. ivptr->hold=0;
  115. return FUNCOKAY;
  116. }
  117.  
  118.  
  119. static int fillBuff(object instance)
  120. {
  121. int         x;
  122. int (*rdSrc)(object);
  123. instVars *     ivptr;
  124.  
  125. if(NULL==(ivptr=getIVptr(instance))) return EOF;
  126. (method) rdSrc=g(GEN(getByte), ivptr->ioObj);
  127. for(ivptr->curPos=0;ivptr->curPos<ivptr->bsize;ivptr->curPos++)
  128.     {
  129.     if(EOF==(x=rdSrc(ivptr->ioObj))) return x;
  130.     (unsigned char)ivptr->buffer[ivptr->curPos++]=x;
  131.     }
  132. ivptr->curPos=0;
  133. return x;
  134. }
  135.  
  136.  
  137. imethod long m4getPos(object instance)
  138. {
  139. long         rv;
  140. instVars *     ivptr;
  141.  
  142. if(NULL==(ivptr=getIVptr(instance)) || m4Flush(instance))
  143.     {
  144.     rv = -1;
  145.     }
  146. else
  147.     {
  148.     rv=g(GEN(getPos))(ivptr->ioObj);
  149.     if(rv<0) ivptr->flags |= S_ERR;
  150.     }
  151. return rv;
  152. }
  153.  
  154.  
  155. imethod object m4setPos(object instance, long newPos, int whence)
  156. {
  157. object         rv=FUNCFAIL;
  158. instVars *    ivptr;
  159.  
  160. if(NULL!=(ivptr=getIVptr(instance)) &&
  161.     FUNCOKAY==(rv=m4Flush(instance)))
  162.     {
  163.     if(newPos==0) ivptr->flags &= (S_RDWR | S_BUF | S_LBUF | S_BIN);
  164.     else ivptr->flags &= (S_RDWR | S_BUF | S_LBUF | S_BIN | S_ERR);
  165.     if(FUNCFAIL==(rv= g(GEN(setPos))(ivptr->ioObj, newPos, whence)))
  166.     ivptr->flags|=S_EOS;
  167.     }
  168. else ivptr->flags |= S_ERR;
  169. return rv;
  170. }
  171.  
  172.  
  173. imethod object m4clrErr(object instance)
  174. {
  175. instVars * ivptr;
  176.  
  177. if(NULL==(ivptr=getIVptr(instance)) || g(GEN(clrErr))(ivptr->ioObj))
  178.     return FUNCFAIL;
  179. ivptr->flags&=(S_RDWR | S_BUF | S_LBUF | S_BIN);
  180. return FUNCOKAY;
  181. }
  182.  
  183.  
  184. imethod object m4Stat(object instance)
  185. {
  186. return (object) ((instVars *) getIVptr(instance))->flags;
  187. }
  188.  
  189.  
  190. imethod int m4Putc(object instance, char c)
  191. {
  192. int         rv=EOF;
  193. instVars *    ivptr;
  194.  
  195. if(NULL==(ivptr=getIVptr(instance))) goto done;
  196. if(OKAY_W)
  197.     {
  198.     if(c=='\n' && !(ivptr->flags & S_BIN))
  199.     {
  200.     m4Putc(instance,'\r');
  201.     }
  202.     SET_W;
  203.     if(ivptr->flags & S_BUF)
  204.     {
  205.     if(ivptr->curPos>=ivptr->bsize)
  206.         {
  207.         if(m4Flush(instance)) goto done;
  208.         }
  209.     rv=((unsigned char)ivptr->buffer[ivptr->curPos++]=c);
  210.     if(c=='\n' && ivptr->flags&S_LBUF)
  211.         {
  212.         m4Flush(instance);
  213.         }
  214.     }
  215.     else rv=(g(GEN(putByte))(ivptr->ioObj, c))?EOF:c;
  216.     if(rv==EOF) ivptr->flags|=S_EOS;
  217.     }
  218. else ivptr->flags|=S_ERR;
  219. done:
  220. return rv;
  221. }
  222.  
  223.  
  224. imethod int m4Getc(object instance)
  225. {
  226. int         rv=EOF;
  227. instVars *    ivptr;
  228.  
  229. if(NULL==(ivptr=getIVptr(instance))) return rv;
  230. restart:
  231. rv=EOF;
  232. if(OKAY_R)
  233.     {
  234.     if(ivptr->flags & S_BUF)
  235.     {
  236.     if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
  237.         {
  238.         SET_R;
  239.         if(EOF==(rv=fillBuff(instance))) goto done;
  240.         }
  241.     rv=((unsigned char)ivptr->buffer[ivptr->curPos++]);
  242.     }
  243.     else
  244.     {
  245.     SET_R;
  246.     if(ivptr->hold!=0)
  247.         {
  248.         rv=ivptr->hold;
  249.         ivptr->hold=0;
  250.         }
  251.     else rv=((INTRV)g)(GEN(getByte))(ivptr->ioObj);
  252.     }
  253.     if(rv==EOF) ivptr->flags |= S_EOS;
  254.     }
  255. else ivptr->flags |= S_ERR;
  256. done:
  257. if((unsigned char)rv=='\r' && !(ivptr->flags&S_BIN))goto restart;
  258. return rv;
  259. }
  260.  
  261.  
  262.  
  263. imethod int m4UnGet(object instance, char c)
  264. {
  265. int         rv=EOF;
  266. instVars *    ivptr;
  267.  
  268. if(NULL==(ivptr=getIVptr(instance))) return rv;
  269. if(OKAY_R && ivptr->flags & S_IN)
  270.     {
  271.     if(ivptr->flags&=S_BUF)
  272.     {
  273.     if(ivptr->curPos>0)
  274.     rv=((unsigned char)ivptr->buffer[--ivptr->curPos]=c);
  275.     }
  276.     else rv=((unsigned char)ivptr->hold=c);
  277.     }
  278. if(rv==EOF) ivptr->flags|=S_ERR;
  279. return rv;
  280. }
  281.  
  282.  
  283.  
  284. imethod object m4Puts(object instance, object dataObj)
  285. {
  286. char *        s;
  287. int        rv=EOF;
  288. int         x=0;
  289. method        direct;
  290. instVars *    ivptr;
  291.  
  292. dataObj=g(GEN(asString))(dataObj);
  293. s=((VDPTRRV)g)(GEN(addressOf))(dataObj);
  294. if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
  295.  
  296. if(OKAY_W && s!=NULL)
  297.     {
  298.     SET_W;
  299.     if(ivptr->flags & S_BUF)
  300.     {
  301.     while(s[x]!=0)
  302.         {
  303.         if(s[x]=='\n' && !(ivptr->flags&S_BIN))
  304.         {
  305.         rv=m4Putc(instance,'\r');
  306.         }
  307.         if(ivptr->curPos>=ivptr->bsize)
  308.         {
  309.         if(m4Flush(instance))
  310.             {
  311.             rv=EOF;
  312.             break;
  313.             }
  314.         }
  315.         rv=((unsigned char)ivptr->buffer[ivptr->curPos++]=s[x]);
  316.         if(s[x]=='\n' && ivptr->flags&S_LBUF && ivptr->curPos>0)
  317.         {
  318.         if(m4Flush(instance))
  319.             {
  320.             rv=EOF;
  321.             break;
  322.             }
  323.         }
  324.         x++;
  325.         }
  326.     }
  327.     else
  328.     {
  329.     direct=g(GEN(putByte), ivptr->ioObj);
  330.     while(s[x]!=0)
  331.         {
  332.         if(s[x]=='\n' && !(ivptr->flags&S_BIN))
  333.         {
  334.         rv=(direct(ivptr->ioObj,'\r'))?EOF:'\r';
  335.         if(rv==EOF) break;
  336.         }
  337.         rv=s[x++];
  338.         rv=(direct(ivptr->ioObj,(char) rv))?EOF:rv;
  339.         if(rv==EOF) break;
  340.         }
  341.     }
  342.     if(rv==EOF) ivptr->flags |= S_EOS;
  343.     }
  344. else ivptr->flags |= S_ERR;
  345. return (rv==EOF)?FUNCFAIL:FUNCOKAY;
  346. }
  347.  
  348.  
  349. imethod object m4Gets(object instance, int max)
  350. {
  351. int         x=0;
  352. int        rv=EOF;
  353. int (*direct)(object);
  354. instVars *    ivptr;
  355. char *        d;
  356. object        newStr;
  357.  
  358. if(NULL==(ivptr=getIVptr(instance))) return (object) NULL;
  359. d=s_malloc(max);
  360. if(OKAY_R && d!=NULL)
  361.     {
  362.     if(ivptr->flags & S_BUF)
  363.     {
  364.     rv=0;
  365.     if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
  366.         {
  367.         SET_R;
  368.         if(EOF==(rv=fillBuff(instance))) x=max;
  369.         }
  370.     while(x<max-1)
  371.         {
  372.         d[x]=(unsigned char)ivptr->buffer[ivptr->curPos++];
  373.         if(ivptr->curPos>=ivptr->bsize &&
  374.         EOF==(rv=fillBuff(instance))) break;
  375.         if(d[x]=='\r' && !(ivptr->flags&S_BIN)) continue;
  376.         if(d[x++]=='\n') break;
  377.         }
  378.     d[x]=0;
  379.     }
  380.     else
  381.     {
  382.     SET_R;
  383.     (method) direct = g(GEN(getByte),ivptr->ioObj);
  384.     while(x<max-1)
  385.         {
  386.         if(EOF==(rv=direct(ivptr->ioObj)))
  387.         break;
  388.         if((d[x]=(unsigned char) rv)=='\r'
  389.         && !(ivptr->flags&S_BIN)) continue;
  390.         if(d[x++]=='\n') break;
  391.         }
  392.     d[x]=0;
  393.     }
  394.     if(rv==EOF)
  395.     {
  396.     ivptr->flags|=S_EOS;
  397.     return (object) NULL;
  398.     }
  399.     newStr=g(New)(String,d);
  400.     s_free(d);
  401.     return newStr;
  402.     }
  403. ivptr->flags|=S_ERR;
  404. return (object) NULL;
  405. }
  406.  
  407.  
  408. imethod int m4Write(object instance, const char * ptr, word size,
  409.                                 word n)
  410. {
  411. method         direct;
  412. word         x,max;
  413. int         rv=0;
  414. instVars *    ivptr;
  415.  
  416. if(NULL==(ivptr=getIVptr(instance))) return EOF;
  417. if(OKAY_W && ptr != NULL && size > 0 && n > 0)
  418.     {
  419.     SET_W;
  420.     if(ivptr->flags & S_BUF)
  421.     {
  422.     for(x=0,max=size*n;x<max;x++)
  423.         {
  424.         if(ptr[x]=='\n' && !(ivptr->flags&S_BIN))
  425.         {
  426.         m4Putc(instance,'\r');
  427.         }
  428.         if(ivptr->curPos>=ivptr->bsize)
  429.         {
  430.         if(m4Flush(instance))
  431.             {
  432.             rv=EOF;
  433.             break;
  434.             }
  435.         }
  436.         (unsigned char)ivptr->buffer[ivptr->curPos++]=ptr[x];
  437.         if(ptr[x]=='\n' && ivptr->flags&S_LBUF && ivptr->curPos>0)
  438.         {
  439.         if(m4Flush(instance))
  440.             {
  441.             rv=EOF;
  442.             break;
  443.             }
  444.         }
  445.         }
  446.     }
  447.     else
  448.     {
  449.     direct=g(GEN(putByte),ivptr->ioObj);
  450.     for(x=0,max=size*n;x<max;x++)
  451.         {
  452.         if(ptr[x]=='\n' && !(ivptr->flags&S_BIN))
  453.         {
  454.         if(direct(ivptr->ioObj,'\r'))
  455.             {
  456.             rv=EOF;
  457.             break;
  458.             }
  459.         }
  460.         if(direct(ivptr->ioObj,ptr[x]))
  461.         {
  462.         rv=EOF;
  463.         break;
  464.         }
  465.         }
  466.     }
  467.     if(EOF==rv)
  468.     {
  469.     ivptr->flags|=S_EOS;
  470.     }
  471.     else
  472.     {
  473.     rv=(max>x)?x:max;
  474.     }
  475.     }
  476. else
  477.     {
  478.     ivptr->flags|=S_ERR;
  479.     }
  480. return rv;
  481. }
  482.  
  483.  
  484.  
  485. imethod int m4Read(object instance, char * ptr, word size, word n)
  486. {
  487. word         x,max;
  488. int (*direct)(object);
  489. int         rv=0;
  490. instVars *    ivptr;
  491.  
  492. if(NULL==(ivptr=getIVptr(instance))) return EOF;
  493. if(OKAY_R && ptr != NULL && size > 0 && n > 0)
  494.     {
  495.     if(ivptr->flags & S_BUF)
  496.     {
  497.     if(!(ivptr->flags & S_IN) || ivptr->curPos>=ivptr->bsize)
  498.         {
  499.         SET_R;
  500.         if(EOF==(rv=fillBuff(instance))) size=0;
  501.         }
  502.     for(x=0,max=size*n;x<max;x++)
  503.         {
  504.         ptr[x]=(unsigned char)ivptr->buffer[ivptr->curPos++];
  505.         if(ivptr->curPos>=ivptr->bsize)
  506.         if(EOF==(rv=fillBuff(instance))) break;
  507.         if(ptr[x]=='\r' && !(ivptr->flags&S_BIN))
  508.         {
  509.         x--;
  510.         continue;
  511.         }
  512.         }
  513.     }
  514.     else
  515.     {
  516.     SET_R;
  517.     (method) direct = g(GEN(getByte), ivptr->ioObj);
  518.     for(x=0,max=size*n;x<max;x++)
  519.         {
  520.         if(EOF==(rv=direct(ivptr->ioObj)))
  521.         break;
  522.         if((ptr[x]=(unsigned char) rv)=='\r'
  523.         && !(ivptr->flags&S_BIN))
  524.         {
  525.         x--;
  526.         continue;
  527.         }
  528.         }
  529.     }
  530.     if(rv==EOF)
  531.     {
  532.     ivptr->flags|=S_EOS;
  533.     }
  534.     else
  535.     {
  536.     rv=(x<max)?x:max;
  537.     }
  538.     }
  539. else ivptr->flags|=S_ERR;
  540. return rv;
  541. }
  542.  
  543.  
  544. CLASS_INSTALL
  545. {
  546. if(END==(CLASS=g(New)(Class, 0, sizeof(instVars), END))
  547.     || addGMthd(CLASS, New, (method) m4New)
  548.     || ADDGM(getPos) || ADDGM(setPos) || ADDGM(Putc) || ADDGM(Getc)
  549.     || ADDGM(Getc) || ADDGM(UnGet) || ADDGM(Puts) || ADDGM(Gets)
  550.     || ADDGM(Write) || ADDGM(Read) || ADDGM(SetBuf) || ADDGM(Flush)
  551.     || ADDGM(clrErr) || ADDGM(Stat)) return FUNCFAIL;
  552. else return FUNCOKAY;
  553. }
  554.  
  555.  
  556.